
#ifndef ColMath_H
#define ColMath_H
#if defined(__sgi) || defined(_WIN32)
#pragma once
#endif

//---------------------------------------------------------------------------
//  Includes
//---------------------------------------------------------------------------

#include <config.h>
#include <col_import_export.h>
#include <vectormath/scalar/cpp/vectormath_aos.h>

namespace col {

//---------------------------------------------------------------------------
//  Forward References
//---------------------------------------------------------------------------

/** Use the float precision to store the graphical data
 */
using Vectormath::Aos::Point3;
using Vectormath::Aos::Vector3;
using Vectormath::Aos::Vector4;
using Vectormath::Aos::Matrix3;
using Vectormath::Aos::Matrix4;
using Vectormath::Aos::Quat;

using Vectormath::Aos::normalize;
using Vectormath::Aos::length;
using Vectormath::Aos::dot;
using Vectormath::Aos::cross;
using Vectormath::Aos::inverse;

class Vector3f;
class Point3f;

//***************************************************************************
//  Vector3f
//***************************************************************************

/** A 3-D vector in array-of-structures format, which has only float accuration,
 *  is used for store geometry data
 */
class Vector3f
{
    float mX;
    float mY;
    float mZ;
#ifndef __GNUC__
    float d;
#endif

public:
    // Default constructor; does no initialization
    // 
    inline Vector3f();

    // Copy a 3-D vector
    // 
    inline Vector3f( const Vector3f &vec );

    // Construct a 3-D vector from x, y, and z elements
    // 
    inline Vector3f( float x, float y, float z );

    // Set all elements of a 3-D vector to the same scalar value
    // 
    explicit inline Vector3f( float scalar );

    // Copy elements from a 3-D vector into a 3-D vector
    // 
    explicit inline Vector3f( const Point3f &pnt );

    // Assign one 3-D vector to another
    // 
    inline Vector3f& operator =( const Vector3f &pnt );

    // Set the x element of a 3-D vector
    // 
    inline Vector3f& setX( float x );

    // Set the y element of a 3-D vector
    // 
    inline Vector3f& setY( float y );

    // Set the z element of a 3-D vector
    // 
    inline Vector3f& setZ( float z );

    // Get the x element of a 3-D vector
    // 
    inline float getX( ) const;

    // Get the y element of a 3-D vector
    // 
    inline float getY( ) const;

    // Get the z element of a 3-D vector
    // 
    inline float getZ( ) const;

    // Set an x, y, or z element of a 3-D vector by index
    // 
    inline Vector3f& setElem( int idx, float value );

    // Get an x, y, or z element of a 3-D vector by index
    // 
    inline float getElem( int idx ) const;

    // Subscripting operator to set or get an element
    // 
    inline float& operator []( int idx );

    // Subscripting operator to get an element
    // 
    inline float operator []( int idx ) const;

    // Add two 3-D vectors
    // 
    inline const Vector3f operator +( const Vector3f & vec ) const;

    // Subtract a 3-D vector from another 3-D vector
    // 
    inline const Vector3f operator -( const Vector3f & vec ) const;

    // Add a 3-D vector to a 3-D point
    // 
    inline const Point3f operator +( const Point3f & pnt ) const;

    // Multiply a 3-D vector by a scalar
    // 
    inline const Vector3f operator *( REAL scalar ) const;

    // Divide a 3-D vector by a scalar
    // 
    inline const Vector3f operator /( REAL scalar ) const;

    // Perform compound assignment and addition with a 3-D vector
    // 
    inline Vector3f& operator +=( const Vector3f& vec );

    // Perform compound assignment and subtraction by a 3-D vector
    // 
    inline Vector3f& operator -=( const Vector3f& vec );

    // Perform compound assignment and multiplication by a scalar
    // 
    inline Vector3f& operator *=( REAL scalar );

    // Perform compound assignment and division by a scalar
    // 
    inline Vector3f& operator /=( REAL scalar );

    // Negate all elements of a 3-D vector
    // 
    inline const Vector3f operator -( ) const;


    // The following 2 functions are used in order that the conversion between
    // Vector3 and Vector3f can be identified and executed automatically by compiler.
    // 
    // Vector3  ==> Vector3f
    inline Vector3f( const Vector3 &vec );
    // Vector3f ==> Vector3
    inline operator Vector3() const;

}
#ifdef __GNUC__
__attribute__ ((aligned(16)))
#endif
;


//***************************************************************************
//  Point3f
//***************************************************************************

/** A 3-D point in array-of-structures format, which has only float accuration,
 *  is used for store geometry data
 */
class Point3f
{
    float mX;
    float mY;
    float mZ;
#ifndef __GNUC__
    float d;
#endif

public:
    // Default constructor; does no initialization
    // 
    inline Point3f();

    // Copy a 3-D point
    // 
    inline Point3f( const Point3f &pnt );

    // Construct a 3-D point from x, y, and z elements
    // 
    inline Point3f( float x, float y, float z );

    // Set all elements of a 3-D point to the same scalar value
    // 
    explicit inline Point3f( float scalar );

    // Copy elements from a 3-D vector into a 3-D point
    // 
    explicit inline Point3f( const Vector3f &vec );

    // Assign one 3-D point to another
    // 
    inline Point3f& operator =( const Point3f &pnt );

    // Set the x element of a 3-D point
    // 
    inline Point3f& setX( float x );

    // Set the y element of a 3-D point
    // 
    inline Point3f& setY( float y );

    // Set the z element of a 3-D point
    // 
    inline Point3f& setZ( float z );

    // Get the x element of a 3-D point
    // 
    inline float getX( ) const;

    // Get the y element of a 3-D point
    // 
    inline float getY( ) const;

    // Get the z element of a 3-D point
    // 
    inline float getZ( ) const;

    // Set an x, y, or z element of a 3-D point by index
    // 
    inline Point3f& setElem( int idx, float value );

    // Get an x, y, or z element of a 3-D point by index
    // 
    inline float getElem( int idx ) const;

    // Subscripting operator to set or get an element
    // 
    inline float& operator []( int idx );

    // Subscripting operator to get an element
    // 
    inline float operator []( int idx ) const;

    // Subtract a 3-D point from another 3-D point
    // 
    inline const Vector3f operator -( const Point3f &pnt ) const;

    // Add a 3-D point to a 3-D vector
    // 
    inline const Point3f operator +( const Vector3f &vec ) const;

    // Subtract a 3-D vector from a 3-D point
    // 
    inline const Point3f operator -( const Vector3f &vec ) const;

    // Perform compound assignment and addition with a 3-D vector
    // 
    inline Point3f & operator +=( const Vector3f &vec );

    // Perform compound assignment and subtraction by a 3-D vector
    // 
    inline Point3f & operator -=( const Vector3f &vec );

    // The following 2 functions are used in order that the conversion between
    // Point3 and Point3f can be identified and executed automatically by compiler.
    // 
    // Point3  ==> Point3f
    inline Point3f( const Point3 &pnt );
    // Point3f ==> Point3
    inline operator Point3() const;

}
#ifdef __GNUC__
__attribute__ ((aligned(16)))
#endif
;

} // namespace col

#include "ColMath.hpp"

#endif // ColMath_H

